package com.example.interesting.idempotent.realize.aop;

import org.springframework.aop.support.AopUtils;
import org.springframework.aop.support.StaticMethodMatcher;
import org.springframework.core.annotation.AnnotatedElementUtils;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @Description: 方法匹配规则
 * @Author: fyw
 * @Date: 2024/4/30 16:47
 * @History
 */
public class IdempotentMethodMatcher extends StaticMethodMatcher {

    private final Class<? extends Annotation> annotationClass;

    public IdempotentMethodMatcher(Class<? extends Annotation> annotationClass) {
        this.annotationClass = annotationClass;
    }

    @Override
    public boolean matches(Method method, Class<?> targetClass) {
        if (AnnotatedElementUtils.hasAnnotation(method, annotationClass)) {
            return true;
        }
        if (Proxy.isProxyClass(targetClass)) {
            return false;
        }
        //获取代理类最匹配方法
        Method mostSpecificMethod = AopUtils.getMostSpecificMethod(method, targetClass);
        return mostSpecificMethod != method && AnnotatedElementUtils.hasAnnotation(mostSpecificMethod, annotationClass);
    }
}
